package com.edu.chat.web.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.edu.buservice.facade.facade.UserFacade;
import com.edu.buservice.facade.model.response.BaseUserInfoDTO;
import com.edu.buservice.util.model.TenantUtil;
import com.edu.chat.facade.model.dto.SceneInfoDTO;
import com.edu.chat.web.common.constants.SceneConstant;
import com.edu.chat.web.common.enums.ResultCodeEnum;
import com.edu.chat.web.common.model.BizException;
import com.edu.chat.web.common.model.R;
import com.edu.chat.web.common.utils.QrUtil;
import com.edu.chat.web.controller.vo.PageQuery;
import com.edu.chat.web.controller.vo.QuerySceneVO;
import com.edu.chat.web.controller.vo.SceneVO;
import com.edu.chat.web.covert.SceneCovert;
import com.edu.chat.web.dto.AnalysisSceneDTO;
import com.edu.chat.web.dto.PageResult;
import com.edu.chat.web.mapper.CsSceneMapper;
import com.edu.chat.web.model.CsScene;
import com.edu.chat.web.model.CsSession;
import com.edu.chat.web.service.CsSceneService;
import com.edu.chat.web.service.CsSessionService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author 86177
 * @description 针对表【cs_scene】的数据库操作Service实现
 * @createDate 2025-02-22 15:02:27
 */
@Service
public class CsSceneServiceImpl extends ServiceImpl<CsSceneMapper, CsScene>
		implements CsSceneService{

	//聊天窗url
	private final String SCENE_URL = "http://localhost:5666/mobile/chat/%s/%s";

	@Autowired
	private QrUtil qrUtil;

	@DubboReference(interfaceClass = UserFacade.class,check = false,timeout = 30000)
	private UserFacade userFacade;

	@Autowired
	private CsSessionService csSessionService;

	@Override
	public SceneInfoDTO querySceneInfoById(Long id) {

		if(id == null) {
			throw new BizException(ResultCodeEnum.PARAM_INVALID, "聊天窗id不能为空");
		}

		CsScene scene = getById(id);

		if(scene != null) {
			return SceneCovert.convertSceneInfoDTO(scene);
		}

		return null;
	}

	@Override
	public R<Boolean> createScene(SceneVO sceneVO) {
		if (sceneVO == null) {
			throw new BizException(ResultCodeEnum.PARAM_INVALID, "场景信息不能为空");
		}

		// 参数验证
		if (sceneVO.getSceneName() == null || sceneVO.getSceneName().isEmpty()) {
			throw new BizException(ResultCodeEnum.PARAM_INVALID, "窗口名称不能为空");
		}
		if (sceneVO.getLibraryIds() == null || sceneVO.getLibraryIds().isEmpty()) {
			throw new BizException(ResultCodeEnum.PARAM_INVALID, "库ID不能为空");
		}
		if (sceneVO.getRobotId() == null || sceneVO.getRobotId().isEmpty()) {
			throw new BizException(ResultCodeEnum.PARAM_INVALID, "机器人ID不能为空");
		}

		//生成url
		if(CollectionUtils.isEmpty(sceneVO.getSceneConfig())){
			sceneVO.setSceneConfig(new HashMap<>());
		}

		sceneVO.setSceneId(IdUtil.getSnowflakeNextId());

		Map<String, String> sceneConfig = sceneVO.getSceneConfig();

		// 生成url
		String url = String.format(SCENE_URL, TenantUtil.getTenantId(),sceneVO.getSceneId());

		sceneConfig.put(SceneConstant.SCENE_URL_KEY, url);

		//生成二维码
		sceneConfig.put(SceneConstant.SCENE_QR_CODE_KEY, qrUtil.getQrCode(url));
		sceneVO.setSceneConfig(sceneConfig);

		// 转换 SceneVO 到 CsScene
		CsScene scene = SceneCovert.convertScene(sceneVO);


		// 保存到数据库
		boolean saveResult = save(scene);
		if (!saveResult) {
			throw new BizException(ResultCodeEnum.FAIL, "创建场景失败");

		}

		return R.success(Boolean.TRUE);
	}

	@Override
	public PageResult<SceneInfoDTO> querySceneList(PageQuery<QuerySceneVO> pageQuery) {

		if (pageQuery == null) {
			throw new BizException(ResultCodeEnum.PARAM_INVALID, "pageQuery不能为空");
		}

		LambdaQueryWrapper<CsScene> queryWrapper = new LambdaQueryWrapper<>();

		//获取分页大小与当前页
		Long size = Optional.ofNullable(pageQuery.getPageSize()).orElse(10L);
		Long current = Optional.ofNullable(pageQuery.getPageNum()).orElse(1L);

		//构建查询条件
		QuerySceneVO query = pageQuery.getQuery();
		if (query != null) {
			if (query.getSceneName() != null) {
				queryWrapper.like(CsScene::getSceneName, pageQuery.getQuery().getSceneName());
			}

			if(query.getStatus() != null){
				queryWrapper.eq(CsScene::getStatus, query.getStatus());
			}
			if(query.getTenantId() != null){
				queryWrapper.eq(CsScene::getTenantId, query.getTenantId());
			}
			if(query.getId() != null){
				queryWrapper.eq(CsScene::getId, query.getId());
			}
		}


		//设置默认删除标记条件
		queryWrapper.eq(CsScene::getDeleted, 0);

		//设置排序
		queryWrapper.orderByDesc(CsScene::getCreatedAt);


		// 查询分页数据
		IPage<CsScene> pageParam = new Page<>(current, size);
		IPage<CsScene> pageResult = page(pageParam, queryWrapper);

		if (Objects.isNull(pageResult)){
			throw new BizException(ResultCodeEnum.DATABASE_ERROR,"数据库查询失败");
		}

		// 构建结果集
		PageResult<SceneInfoDTO> res = new PageResult<>();
		res.setTotal(pageResult.getTotal());
		res.setTotalPages(pageResult.getPages());
		res.setCurrentPage(pageResult.getCurrent());

		if(pageResult.getRecords().isEmpty()){
			return res;
		}

		List<SceneInfoDTO> list = pageResult.getRecords().stream().map(SceneCovert::convertSceneInfoDTO).toList();

		Set<String> collect = list.stream().map(SceneInfoDTO::getCreator).collect(Collectors.toSet());

		if(!CollectionUtils.isEmpty(collect)){
			List<BaseUserInfoDTO> userList = userFacade.queryUserByIds(new ArrayList<>(collect));

			Map<String, BaseUserInfoDTO> userMap = userList.stream().collect(Collectors.toMap(BaseUserInfoDTO::getUserId, userDTO -> userDTO));

			list.forEach(item -> {
				BaseUserInfoDTO userDTO = userMap.get(item.getCreator());

				if(userDTO != null){
					item.setCreatorName(userDTO.getUsername());
				}
			});
		}


		res.setRecords(list);

		return res;
	}

	@Override
	public R<Boolean> updateScene(SceneVO sceneVO) {

		if (sceneVO == null) {
			throw new BizException(ResultCodeEnum.PARAM_INVALID, "场景信息不能为空");
		}

		if (sceneVO.getSceneId() == null) {
			throw new BizException(ResultCodeEnum.PARAM_INVALID, "场景ID不能为空");
		}

		//删除原本场景信息
		removeById(sceneVO.getSceneId());

		//重新创建场景
		return createScene(sceneVO);
	}
	@Override
	public R<List<AnalysisSceneDTO>> querySceneTop10() {
		// 获取当前租户ID
		String tenantId = TenantUtil.getTenantId();
		if (tenantId == null) {
			return R.fail("租户ID不能为空");
		}

		// 设置时间范围：过去7天（包含当天），从七天前的00:00:00到当前日期的23:59:59
		Date now = new Date();
		Date begin = DateUtil.beginOfDay(DateUtil.offsetDay(now, -7));
		Date end = DateUtil.endOfDay(now);

		// 查询符合条件的会话列表
		List<CsSession> csSessions = csSessionService.querySessionByTenantIdAndTime(
				tenantId,
				formatDate(begin),
				formatDate(end)
		);

		// 按场景ID分组统计数量
		Map<Long, Long> sceneCountMap = csSessions.stream()
				.collect(Collectors.groupingBy(CsSession::getSceneId, Collectors.counting()));

		// 获取数量前10的场景ID列表（按数量降序）
		List<Long> top10SceneIds = sceneCountMap.entrySet().stream()
				.sorted(Map.Entry.<Long, Long>comparingByValue().reversed())
				.limit(10)
				.map(Map.Entry::getKey)
				.collect(Collectors.toList());

		if (top10SceneIds.isEmpty()) {
			return R.success(Collections.emptyList());
		}

		// 批量查询场景信息
		List<CsScene> csScenes = listByIds(top10SceneIds);
		Map<Long, CsScene> sceneMap = csScenes.stream()
				.collect(Collectors.toMap(CsScene::getId, Function.identity()));

		// 构建有序结果列表
		List<AnalysisSceneDTO> res = new ArrayList<>();
		for (Long sceneId : top10SceneIds) {
			Long count = sceneCountMap.get(sceneId);
			CsScene scene = sceneMap.get(sceneId);

			if (scene == null) {
				continue; // 忽略无效场景（可添加日志记录）
			}

			AnalysisSceneDTO analysisSceneDTO = new AnalysisSceneDTO();
			analysisSceneDTO.setSceneId(String.valueOf(sceneId));
			analysisSceneDTO.setCount(count.intValue());
			analysisSceneDTO.setSceneName(scene.getSceneName());
			analysisSceneDTO.setTenantId(scene.getTenantId());

			res.add(analysisSceneDTO);
		}

		return R.success(res);
	}

	// 日期格式化辅助方法
	private String formatDate(Date date) {
		return DateUtil.format(date, "yyyy-MM-dd HH:mm:ss");
	}


}




